package hamsterwrench.data.reload;

import java.util.ArrayList;

/**
 * @author Matt
 *
 */
public class ReloadNode {
       
        //declarations
        private ReloadNodeType type;
        private String nodeName;
        private short byteData;
        private short shortData;
        private int intData;
        private long longData;
        private double floatData;
        private String stringData;
        private ArrayList<ReloadNode> nodeTree = new ArrayList<ReloadNode>(0);
       
        //constructors
        /**
         * Creates a RELOAD Node of type Null (0).
         */
        public ReloadNode() {
                type = ReloadNodeType.NULL;
        }
       
        /**
         * Creates a RELOAD NODE of either Byte (1) or Short (2)
         * @param data the data to initialize the node with.
         * @param isByte if the node is a Byte.
         * @throws ReloadOutOfBoundsException if isByte is true but data is not within the bounds of an unsigned byte.
         */
        public ReloadNode(short data, boolean isByte) throws ReloadOutOfBoundsException {
                if(isByte){
                        if(data >= 0 && data < 256){
                                type = ReloadNodeType.BYTE;
                                byteData = data;
                        } else throw new ReloadOutOfBoundsException();
                }
                else{
                        type = ReloadNodeType.SHORT;
                        shortData = data;
                }
        }
       
        /**
         * @param data
         */
        public ReloadNode(int data){
                type = ReloadNodeType.INT;
                intData = data;
        }
       
        /**
         * @param data
         */
        public ReloadNode(long data){
                type = ReloadNodeType.LONG;
                longData = data;
        }
       
        /**
         * @param data
         */
        public ReloadNode(double data){
                type = ReloadNodeType.FLOAT;
                floatData = data;
        }
       
        /**
         * @param data
         */
        public ReloadNode(String data){
                type = ReloadNodeType.STRING;
                stringData = data;
        }
       
        //Child operations
        /**
         * @param name
         * @return
         */
        public boolean hasChild(String name){
                return (getPositionOf(name) > -1);
        }
       
        /**
         * @param name
         * @return
         */
        public int getPositionOf(String name){
                for(int i = 0; i < nodeTree.size(); i++){
                        if(nodeTree.get(i).getNodeName() == name){
                                return i;
                        }
                }
                return -1;
        }
       
        /**
         * @param name
         * @return
         */
        public ReloadNode getChild(String name){
                for(int i = 0; i < nodeTree.size(); i++){
                        if(nodeTree.get(i).getNodeName() == name){
                                return nodeTree.get(i);
                        }
                }
                return null;
        }
        
        public ReloadNode getChild(int index){
        	return nodeTree.get(index);
        }
       
        /**
         * @param node
         */
        public void addChild(ReloadNode node){
                nodeTree.add(node);
        }
       
        /**
         * @param node
         * @param index
         */
        public void addChild(ReloadNode node, int index){
                nodeTree.add(index, node);
        }
       
        /**
         * @param name
         */
        public void dropChild(String name){
                for(int i = 0; i < nodeTree.size(); i++){
                        if(nodeTree.get(i).getNodeName() == name){
                                nodeTree.remove(i);
                                break;
                        }
                }
        }
       
        /**
         * @return
         */
        public int getNumberOfChildren(){
                return nodeTree.size();
        }
       
        //Getters and Setters
       
        /**
         * @return
         */
        public String getNodeName() {
                return nodeName;
        }

        /**
         * @param nodeName
         */
        public void setNodeName(String nodeName) {
                this.nodeName = nodeName;
        }

        /**
         * @return
         */
        public ReloadNodeType getType() {
                return type;
        }

        /**
         * @return
         * @throws ReloadWrongTypeException
         */
        public short getByteData() throws ReloadWrongTypeException {
                if(type == ReloadNodeType.BYTE) return byteData;
                else throw new ReloadWrongTypeException();
        }

        /**
         * @param byteData
         * @throws ReloadWrongTypeException
         * @throws ReloadOutOfBoundsException
         */
        public void setByteData(short byteData) throws ReloadWrongTypeException, ReloadOutOfBoundsException {
                if(type == ReloadNodeType.BYTE){
                        if(byteData >= 0 && byteData < 256) this.byteData = byteData;
                        else throw new ReloadOutOfBoundsException();
                }else throw new ReloadWrongTypeException();
        }

        /**
         * @return
         * @throws ReloadWrongTypeException
         */
        public short getShortData() throws ReloadWrongTypeException  {
                if(type == ReloadNodeType.SHORT) return shortData;
                else throw new ReloadWrongTypeException();
        }

        /**
         * @param shortData
         * @throws ReloadWrongTypeException
         */
        public void setShortData(short shortData) throws ReloadWrongTypeException  {
                if(type == ReloadNodeType.SHORT) this.shortData = shortData;
                else throw new ReloadWrongTypeException();
        }

        /**
         * @return
         * @throws ReloadWrongTypeException
         */
        public int getIntData() throws ReloadWrongTypeException  {
                if(type == ReloadNodeType.INT) return intData;
                else throw new ReloadWrongTypeException();
        }

        /**
         * @param intData
         * @throws ReloadWrongTypeException
         */
        public void setIntData(int intData) throws ReloadWrongTypeException  {
                if(type == ReloadNodeType.INT) this.intData = intData;
                else throw new ReloadWrongTypeException();
        }

        /**
         * @return
         * @throws ReloadWrongTypeException
         */
        public long getLongData() throws ReloadWrongTypeException  {
                if(type == ReloadNodeType.LONG) return longData;
                else throw new ReloadWrongTypeException();
        }

        /**
         * @param longData
         * @throws ReloadWrongTypeException
         */
        public void setLongData(long longData) throws ReloadWrongTypeException  {
                if(type == ReloadNodeType.LONG) this.longData = longData;
                else throw new ReloadWrongTypeException();
        }

        /**
         * @return
         * @throws ReloadWrongTypeException
         */
        public double getFloatData() throws ReloadWrongTypeException  {
                if(type == ReloadNodeType.FLOAT) return floatData;
                else throw new ReloadWrongTypeException();
        }

        /**
         * @param floatData
         * @throws ReloadWrongTypeException
         */
        public void setFloatData(double floatData) throws ReloadWrongTypeException  {
                if(type == ReloadNodeType.FLOAT) this.floatData = floatData;
                else throw new ReloadWrongTypeException();
        }

        /**
         * @return
         * @throws ReloadWrongTypeException
         */
        public String getStringData() throws ReloadWrongTypeException  {
                if(type == ReloadNodeType.STRING) return stringData;
                else throw new ReloadWrongTypeException();
        }

        /**
         * @param stringData
         * @throws ReloadWrongTypeException
         */
        public void setStringData(String stringData) throws ReloadWrongTypeException  {
                if(type == ReloadNodeType.STRING) this.stringData = stringData;
                else throw new ReloadWrongTypeException();
        }
   
     @Override
	public String toString(){
       return nodeName;
     }
       

}
